/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.unesp.demac.bcc.soo.dao;

import br.unesp.demac.bcc.soo.bean.Contato;
import br.unesp.demac.bcc.soo.bean.Endereco;
import br.unesp.demac.bcc.soo.bean.Login;
import br.unesp.demac.bcc.soo.bean.Pessoa;
import br.unesp.demac.bcc.soo.util.FabricaConexao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

/**
 *
 * @author flavioam
 */
public class PessoaDAOImp implements PessoaDAO {

    @Override
    public boolean salvaPessoa(Pessoa p) throws Exception {

        boolean saved = false;
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();
            con.setAutoCommit(false);

            String sqlPessoa = "insert into Pessoas (nome,cpf) values (?,?)";

            PreparedStatement pstmtPessoa = con.prepareStatement(sqlPessoa, Statement.RETURN_GENERATED_KEYS);

            pstmtPessoa.setString(1, p.getNome());
            pstmtPessoa.setString(2, p.getCpf());

            pstmtPessoa.executeUpdate();

            ResultSet keys = pstmtPessoa.getGeneratedKeys();
            keys.next();
            int idPessoa = keys.getInt(1);
            p.setIdPessoa(idPessoa);

            ContatoDAO contatoDAO = new ContatoDAOImp();
            contatoDAO.salvaContato(p, con);

            EnderecoDAO endDAO = new EnderecoDAOImp();
            endDAO.salvaEndereco(p, con);

            LoginDAO loginDAO = new LoginDAOImp();
            loginDAO.salvaLogin(p, con);

            con.commit();

            saved = true;

        } catch (SQLException e) {

            throw new Exception("Erro ao salvar pessoa: " + e.getMessage());

        } finally {
            FabricaConexao.fechar(con);
        }
        return saved;
    }

    @Override
    public ArrayList<Pessoa> selecionaTodosClientes() throws Exception {

        ArrayList<Pessoa> l = new ArrayList<Pessoa>();
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();

            String sql = "select * from Pessoas where idPessoas not in (select Pessoas_idPessoas from Funcionarios)";

            PreparedStatement pstmt = con.prepareStatement(sql);

            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {

                Pessoa p = new Pessoa();
                p.setNome(rs.getString("nome"));
                p.setCpf(rs.getString("cpf"));
                p.setIdPessoa(rs.getInt("idPessoas"));

                LoginDAO lDao = new LoginDAOImp();
                Login login = lDao.selecionaLoginByIdPessoa(p.getIdPessoa());
                p.setLogin(login);

                EnderecoDAO eDao = new EnderecoDAOImp();
                Endereco end = eDao.selecionaEnderecoByIdPessoa(p.getIdPessoa());
                p.setEndereco(end);

                ContatoDAO cDao = new ContatoDAOImp();
                Contato cont = cDao.selecionaContadoByIdPessoa(p.getIdPessoa());
                p.setContato(cont);

                l.add(p);

            }

        } catch (SQLException e) {

            throw new Exception("Erro ao selecionar clientes: " + e.getMessage());

        } finally {
            FabricaConexao.fechar(con);
        }
        return l;
    }

    @Override
    public ArrayList<Pessoa> selecionaTodasPessoas() throws Exception {

        ArrayList<Pessoa> l = new ArrayList<Pessoa>();
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();

            String sql = "select * from Pessoas";

            PreparedStatement pstmt = con.prepareStatement(sql);

            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {

                Pessoa p = new Pessoa();
                p.setNome(rs.getString("nome"));
                p.setCpf(rs.getString("cpf"));
                p.setIdPessoa(rs.getInt("idPessoas"));

                LoginDAO lDao = new LoginDAOImp();
                Login login = lDao.selecionaLoginByIdPessoa(p.getIdPessoa());
                p.setLogin(login);

                EnderecoDAO eDao = new EnderecoDAOImp();
                Endereco end = eDao.selecionaEnderecoByIdPessoa(p.getIdPessoa());
                p.setEndereco(end);

                ContatoDAO cDao = new ContatoDAOImp();
                Contato cont = cDao.selecionaContadoByIdPessoa(p.getIdPessoa());
                p.setContato(cont);

                l.add(p);

            }

        } catch (SQLException e) {

            throw new Exception("Erro ao selecionar pessoas: " + e.getMessage());

        } finally {
            FabricaConexao.fechar(con);
        }
        return l;
    }

    @Override
    public boolean deletaPessoa(Pessoa p) throws Exception {

        boolean deleted = false;
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();

            String sqlPessoa = "delete from Pessoas where idPessoas = ?";

            PreparedStatement pstmtPessoa = con.prepareStatement(sqlPessoa);

            pstmtPessoa.setInt(1, p.getIdPessoa());
            pstmtPessoa.executeUpdate();

            deleted = true;

        } catch (SQLException e) {

            throw new Exception("Erro ao deletar pessoa: " + e.getMessage());

        } finally {
            FabricaConexao.fechar(con);
        }
        return deleted;
    }

    @Override
    public boolean editaPessoa(Pessoa p) throws Exception {

        boolean saved = false;
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();
            con.setAutoCommit(false);

            String sqlPessoa = "update Pessoas set  cpf = ? where idPessoas = ?";

            PreparedStatement pstmtPessoa = con.prepareStatement(sqlPessoa);

            pstmtPessoa.setString(1, p.getCpf());
            pstmtPessoa.setInt(2, p.getIdPessoa());

            pstmtPessoa.executeUpdate();

            ContatoDAO contatoDAO = new ContatoDAOImp();
            contatoDAO.editaContato(p, con);

            EnderecoDAO endDAO = new EnderecoDAOImp();
            endDAO.editaEndereco(p, con);

            LoginDAO loginDAO = new LoginDAOImp();
            loginDAO.editaLogin(p, con);

            con.commit();

            saved = true;

        } catch (SQLException e) {

            con.rollback();
            e.printStackTrace();
            throw new Exception("Erro ao editar pessoa: " + e.getMessage());

        } finally {
            FabricaConexao.fechar(con);
        }
        return saved;
    }

    @Override
    public Pessoa selecionaClienteById(int id) throws Exception {

        Pessoa p = null;
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();

            String sql = "select * from Pessoas where idPessoas  = ?";

            PreparedStatement pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, id);

            ResultSet rs = pstmt.executeQuery();

            if (rs.next()) {

                p = new Pessoa();
                p.setNome(rs.getString("nome"));
                p.setCpf(rs.getString("cpf"));
                p.setIdPessoa(rs.getInt("idPessoas"));

                LoginDAO lDao = new LoginDAOImp();
                Login login = lDao.selecionaLoginByIdPessoa(p.getIdPessoa());
                p.setLogin(login);

                EnderecoDAO eDao = new EnderecoDAOImp();
                Endereco end = eDao.selecionaEnderecoByIdPessoa(p.getIdPessoa());
                p.setEndereco(end);

                ContatoDAO cDao = new ContatoDAOImp();
                Contato cont = cDao.selecionaContadoByIdPessoa(p.getIdPessoa());
                p.setContato(cont);

            }

        } catch (SQLException e) {

            throw new Exception("Erro ao selecionar pessoa: " + e.getMessage());

        } finally {
            FabricaConexao.fechar(con);
        }
        return p;
    }
}
